bitkeeper revision 1.22.1.1 (3e3e99f1o3TNE3GpOg3lVm9IdI7Z7Q)
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Mon, 3 Feb 2003 16:33:53 +0000 (16:33 +0000)
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Mon, 3 Feb 2003 16:33:53 +0000 (16:33 +0000)
Many files:
  We now have a shared read-only machine->physical mapping table at start of hypervisor virtual address region.

xen-2.4.16/arch/i386/Rules.mk
xen-2.4.16/arch/i386/boot/boot.S
xen-2.4.16/arch/i386/mm.c
xen-2.4.16/arch/i386/xeno.lds
xen-2.4.16/common/domain.c
xen-2.4.16/common/memory.c
xen-2.4.16/include/asm-i386/page.h
xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h
xen-2.4.16/include/xeno/config.h

index 6923537ff333f86e88075c6e6752b1c282de2d61..323730c8ee8083de50ac04efd256efc6c95f63b8 100644 (file)
@@ -4,7 +4,7 @@
 CC := gcc
 LD := ld
 # Linker should relocate monitor to this address
-MONITOR_BASE := 0xFC100000
+MONITOR_BASE := 0xFC500000
 # Bootloader should load monitor to this real address
 LOAD_BASE    := 0x00100000
 CFLAGS  := -fno-builtin -O3 -Wall -DMONITOR_BASE=$(MONITOR_BASE) 
index bd62d8ffba2825f517bdf768e15505cc756ee873..091b76057636dd33260372f682e7dbc79c9c14dd 100644 (file)
@@ -216,13 +216,15 @@ nopaging_gdt_descr:
         .long   SYMBOL_NAME(gdt_table)-__PAGE_OFFSET
         
         ALIGN
+/* NB. Rings != 0 get access up to 0xFC400000. This allows access to the */
+/*     machine->physical mapping table. Ring 0 can access all memory.    */
 ENTRY(gdt_table)
         .quad 0x0000000000000000     /* NULL descriptor */
         .quad 0x0000000000000000     /* not used */
-        .quad 0x00cfba000000bfff     /* 0x11 ring 1 3.95GB code at 0x0 */
-        .quad 0x00cfb2000000bfff     /* 0x19 ring 1 3.95GB data at 0x0 */
-        .quad 0x00cffa000000bfff     /* 0x23 ring 3 3.95GB code at 0x0 */
-        .quad 0x00cff2000000bfff     /* 0x2b ring 3 3.95GB data at 0x0 */
+        .quad 0x00cfba000000c3ff     /* 0x11 ring 1 3.95GB code at 0x0 */
+        .quad 0x00cfb2000000c3ff     /* 0x19 ring 1 3.95GB data at 0x0 */
+        .quad 0x00cffa000000c3ff     /* 0x23 ring 3 3.95GB code at 0x0 */
+        .quad 0x00cff2000000c3ff     /* 0x2b ring 3 3.95GB data at 0x0 */
         .quad 0x00cf9a000000ffff     /* 0x30 ring 0 4.00GB code at 0x0 */
         .quad 0x00cf92000000ffff     /* 0x38 ring 0 4.00GB data at 0x0 */
         .fill NR_CPUS,8,0             /* space for TSS's */
index 29553a9c9b1a5ff3cdb1a5a1b53d4e937c61ff7e..2d4d8ddf5206743c6f337caf7e7efd72b7d9e026 100644 (file)
@@ -73,8 +73,14 @@ void __init paging_init(void)
     /* Create page table for ioremap(). */
     ioremap_pt = (void *)get_free_page(GFP_KERNEL);
     clear_page(ioremap_pt);
-    idle0_pg_table[MAPCACHE_VIRT_START >> L2_PAGETABLE_SHIFT] = 
+    idle0_pg_table[IOREMAP_VIRT_START >> L2_PAGETABLE_SHIFT] = 
         mk_l2_pgentry(__pa(ioremap_pt) | PAGE_HYPERVISOR);
+
+    /* Create read-only mapping of MPT for guest-OS use. */
+    idle0_pg_table[READONLY_MPT_VIRT_START >> L2_PAGETABLE_SHIFT] =
+        idle0_pg_table[RDWR_MPT_VIRT_START >> L2_PAGETABLE_SHIFT];
+    mk_l2_readonly(idle0_pg_table + 
+                   (READONLY_MPT_VIRT_START >> L2_PAGETABLE_SHIFT));
 }
 
 void __init zap_low_mappings (void)
index aff3932ea36ace6a9e541e624f954fa0646d4b51..5947ebada55496752f38b03eba0a5f48f446df20 100644 (file)
@@ -6,7 +6,7 @@ OUTPUT_ARCH(i386)
 ENTRY(start)
 SECTIONS
 {
-  . = 0xFC000000 + 0x100000;
+  . = 0xFC400000 + 0x100000;
   _text = .;                   /* Text and read-only data */
   .text : {
        *(.text)
index 96088948329ffc6e22b320b3c1792c024be6040e..b6279f52fe72efa752a0ee73ef4a8bac60524748 100644 (file)
@@ -576,6 +576,9 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params)
     net_ring_t *net_ring;
     net_vif_t *net_vif;
 
+    /* Sanity! */
+    if ( p->domain != 0 ) BUG();
+
     if ( strncmp(__va(mod[0].mod_start), "XenoGues", 8) )
     {
         printk("DOM%d: Invalid guest OS image\n", dom);
@@ -622,10 +625,13 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params)
     memset(l2tab, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE*sizeof(l2_pgentry_t));
     p->mm.pagetable = mk_pagetable(phys_l2tab);
 
+    /* Domain 0 gets WRITE access to the read-only machine->physical table. */
+    mk_l2_writeable(l2tab + (READONLY_MPT_VIRT_START >> L2_PAGETABLE_SHIFT));
+
     /*
-     * NB. The upper limit on this loop does one extra page + pages for frame table. 
-     * This is to make sure a pte exists when we want to map the shared_info struct
-     * and frame table struct.
+     * NB. The upper limit on this loop does one extra page + pages for frame
+     * table. This is to make sure a pte exists when we want to map the
+     * shared_info struct and frame table struct.
      */
 
     ft_pages = frame_table_size >> PAGE_SHIFT;
index ed913e5752a703276250e7d7948ddccb7501e612..ec11ec6e5de107f4cbb9297a11384cdd04620f30 100644 (file)
@@ -224,15 +224,15 @@ void __init init_frametable(unsigned long nr_pages)
     max_page = nr_pages;
     frame_table_size = nr_pages * sizeof(struct pfn_info);
     frame_table_size = (frame_table_size + PAGE_SIZE - 1) & PAGE_MASK;
-    free_pfns = nr_pages - 
-        ((MAX_MONITOR_ADDRESS + frame_table_size) >> PAGE_SHIFT);
-
-    frame_table = phys_to_virt(MAX_MONITOR_ADDRESS);
+    frame_table = (frame_table_t *)FRAMETABLE_VIRT_START;
     memset(frame_table, 0, frame_table_size);
 
+    free_pfns = nr_pages - 
+        ((__pa(frame_table) + frame_table_size) >> PAGE_SHIFT);
+
     /* Put all domain-allocatable memory on a free list. */
     INIT_LIST_HEAD(&free_list);
-    for( page_index = (MAX_MONITOR_ADDRESS + frame_table_size) >> PAGE_SHIFT; 
+    for( page_index = (__pa(frame_table) + frame_table_size) >> PAGE_SHIFT; 
          page_index < nr_pages; 
          page_index++ )      
     {
@@ -364,6 +364,12 @@ static int get_l2_table(unsigned long page_nr)
               DOMAIN_ENTRIES_PER_L2_PAGETABLE] =
         mk_l2_pgentry(__pa(current->mm.perdomain_pt) | __PAGE_HYPERVISOR);
 
+    /*
+     * DOM0 has the MPT mapped as WRITABLE.
+     * 'p_l2_entry' happens to be pointing at the right place at this point :-)
+     */
+    if ( current->domain == 0 ) mk_l2_writeable(p_l2_entry);
+
  out:
     unmap_domain_mem(p_l2_entry);
     return ret;
index b0d68a324a710846ab44e25517a954e597189ad5..5b2d1fabc53fa5d327a8203989b495d26146e6f3 100644 (file)
@@ -73,7 +73,7 @@ typedef struct { unsigned long pt_lo; } pagetable_t;
 #define l1_pgentry_empty(_x) (!l1_pgentry_val(_x))
 #define l2_pgentry_empty(_x) (!l2_pgentry_val(_x))
 
-#define __PAGE_OFFSET          (0xFC000000)
+#define __PAGE_OFFSET          (0xFC400000)
 #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
 #define __pa(x)                        ((unsigned long)(x)-PAGE_OFFSET)
 #define __va(x)                        ((void *)((unsigned long)(x)+PAGE_OFFSET))
@@ -83,7 +83,7 @@ typedef struct { unsigned long pt_lo; } pagetable_t;
 
 /* High table entries are reserved by the hypervisor. */
 #define DOMAIN_ENTRIES_PER_L2_PAGETABLE            \
-  (PAGE_OFFSET >> L2_PAGETABLE_SHIFT)
+  (HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT)
 #define HYPERVISOR_ENTRIES_PER_L2_PAGETABLE \
   (ENTRIES_PER_L2_PAGETABLE - DOMAIN_ENTRIES_PER_L2_PAGETABLE)
 
@@ -153,6 +153,16 @@ __asm__ __volatile__("invlpg %0": :"m" (*(char *) (__addr)))
 #define PAGE_HYPERVISOR_RO MAKE_GLOBAL(__PAGE_HYPERVISOR_RO)
 #define PAGE_HYPERVISOR_NOCACHE MAKE_GLOBAL(__PAGE_HYPERVISOR_NOCACHE)
 
+#define mk_l2_writeable(_p) \
+    (*(_p) = mk_l2_pgentry(l2_pgentry_val(*(_p)) |  _PAGE_RW))
+#define mk_l2_readonly(_p) \
+    (*(_p) = mk_l2_pgentry(l2_pgentry_val(*(_p)) & ~_PAGE_RW))
+#define mk_l1_writeable(_p) \
+    (*(_p) = mk_l1_pgentry(l1_pgentry_val(*(_p)) |  _PAGE_RW))
+#define mk_l1_readonly(_p) \
+    (*(_p) = mk_l1_pgentry(l1_pgentry_val(*(_p)) & ~_PAGE_RW))
+
+
 #ifndef __ASSEMBLY__
 static __inline__ int get_order(unsigned long size)
 {
index 9038d51d11f307daf5f893bd83fc82a362ee95dd..6052c7b6980b584613ff3b53184ee5963f94fdf7 100644 (file)
 #ifndef __HYPERVISOR_IF_H__
 #define __HYPERVISOR_IF_H__
 
-/* Virtual addresses beyond this are inaccessible by guest OSes. */
+/*
+ * Virtual addresses beyond this are not modifiable by guest OSes.
+ * The machine->physical mapping table starts at this address, read-only
+ * to all domains except DOM0.
+ */
 #define HYPERVISOR_VIRT_START (0xFC000000UL)
 
 typedef struct trap_info_st
index f139a80066bc8c02b72854af3541e7c1418a58b8..54fcf6f83f9714266a7331182f253703e93d251e 100644 (file)
 #define __cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
 #define ____cacheline_aligned __cacheline_aligned
 
-/* 0-16MB is fixed monitor space. 0-52MB is direct-mapped at top of memory.*/
+/*** Hypervisor owns top 64MB of virtual address space. ***/
+#define HYPERVISOR_VIRT_START (0xFC000000UL)
+
+/*
+ * First 4MB are mapped read-only for all. It's for the machine->physical
+ * mapping table (MPT table). The following are virtual addresses.
+ */
+#define READONLY_MPT_VIRT_START (HYPERVISOR_VIRT_START)
+#define READONLY_MPT_VIRT_END   (READONLY_MPT_VIRT_START + (4*1024*1024))
+/*
+ * Next 16MB is fixed monitor space, which is part of a 48MB direct-mapped
+ * memory region. The following are machine addresses.
+ */
 #define MAX_MONITOR_ADDRESS   (16*1024*1024)
 #define MAX_DMA_ADDRESS       (16*1024*1024)
-#define MAX_DIRECTMAP_ADDRESS (52*1024*1024)
+#define MAX_DIRECTMAP_ADDRESS (48*1024*1024)
+/* And the virtual addresses for the direct-map region... */
+#define DIRECTMAP_VIRT_START  (READONLY_MPT_VIRT_END)
+#define DIRECTMAP_VIRT_END    (DIRECTMAP_VIRT_START + MAX_DIRECTMAP_ADDRESS)
+#define MONITOR_VIRT_START    (DIRECTMAP_VIRT_START)
+#define MONITOR_VIRT_END      (MONITOR_VIRT_START + MAX_MONITOR_ADDRESS)
+#define RDWR_MPT_VIRT_START   (MONITOR_VIRT_END)
+#define RDWR_MPT_VIRT_END     (RDWR_MPT_VIRT_START + (4*1024*1024))
+#define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END)
+#define FRAMETABLE_VIRT_END   (DIRECTMAP_VIRT_END)
 /* Next 4MB of virtual address space used for per-domain mappings (eg. GDT). */
-#define PERDOMAIN_VIRT_START  (PAGE_OFFSET + MAX_DIRECTMAP_ADDRESS)
+#define PERDOMAIN_VIRT_START  (DIRECTMAP_VIRT_END)
 #define PERDOMAIN_VIRT_END    (PERDOMAIN_VIRT_START + (4*1024*1024))
 /* Penultimate 4MB of virtual address space used for domain page mappings. */
 #define MAPCACHE_VIRT_START   (PERDOMAIN_VIRT_END)